#include "atspi/atspi.h"
#include <stdio.h>
#include <stdlib.h>

/*
 * 本程序演示如何获取桌面根节点下所有一级子节点（即所有支持无障碍的应用程序），
 * 并打印它们的名称和角色。类似于 accerciser 左侧树的第一层。
 */

int main()
{
    // 初始化 AT-SPI
    if (atspi_init() != 0)
    {
        fprintf(stderr, "AT-SPI 初始化失败\n");
        return -1;
    }

    printf("桌面 Accessible 应用程序（第一层）:\n");
    printf("================================\n");

    // 获取桌面根节点
    AtspiAccessible *desktop = atspi_get_desktop(0);
    if (!desktop)
    {
        fprintf(stderr, "无法获取 desktop accessible 对象\n");
        atspi_exit();
        return -1;
    }

    // 获取桌面下的应用程序数量
    GError *error = NULL;
    gint app_count = atspi_accessible_get_child_count(desktop, &error);
    if (error)
    {
        fprintf(stderr, "获取应用数量出错: %s\n", error->message);
        g_error_free(error);
        g_object_unref(desktop);
        atspi_exit();
        return -1;
    }

    printf("通过atspi_accessible_get_child_count统计到的应用程序数量: %d\n", app_count);

    // 遍历所有一级子节点（应用程序）
    int valid_count = 0;
    for (gint i = 0; i < app_count; i++)
    {
        error = NULL;
        // 获取第 i 个应用程序
        // 注意：这里的 app 可能是 NULL 或者不是有效的 GObject，所以
        // 需要检查返回值和错误。
        AtspiAccessible *app = atspi_accessible_get_child_at_index(desktop, i, &error);
        if (error || !app || !G_IS_OBJECT(app))
        {
            fprintf(stderr, "获取第 %d 个应用出错: %s\n", i, error ? error->message : "app无效");
            if (error)
                g_error_free(error);
            continue;
        }

        valid_count++;

        // 获取应用名称
        char *name = atspi_accessible_get_name(app, NULL);
        // 获取应用角色
        AtspiRole role = atspi_accessible_get_role(app, NULL);
        const char *role_name = atspi_role_get_name(role);

        // 打印应用信息
        printf("├─ %s (%s)\n", name ? name : "Unnamed", role_name ? role_name : "N/A");

        g_free(name);
        if (app && G_IS_OBJECT(app))
            g_object_unref(app);
        else if (app)
            fprintf(stderr, "警告：节点 '%s' 不是有效的 GObject，无法释放！\n", name ? name : "Unnamed");
    }

    printf("理论子节点数量: %d, 实际有效节点数量: %d\n", app_count, valid_count);
    
    g_object_unref(desktop);
    atspi_exit();
    return 0;
}